﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
	
    public class NXTComm
    {
        //Class to read and write over serial com.
        private SerialPort _BluetoothConnection;

        // Declare a 2 bytes vector to store the message length header 
        private Byte[] MessageLength= {0x00, 0x00};

        //Delegate and events used to pass along information received over bluetooth
        public delegate void message(int[] recievedMessage);
        public event message messageReceived;.,

		//Delegate and events used to pass transmission data as a string for debugging
        public delegate void updateStatusBox(string message);
        public event updateStatusBox rxtx;

        /// <summary>
        /// Creates a new NXTComm object
        /// </summary>
        public NXTComm(String comPort)
        {
            _BluetoothConnection = new SerialPort();
            _BluetoothConnection.PortName = comPort;
            _BluetoothConnection.ReadTimeout = 1500;
            _BluetoothConnection.ReceivedBytesThreshold = 8;

            //When we recieve data parse it
            _BluetoothConnection.DataReceived += new SerialDataReceivedEventHandler(_BluetoothConnection_DataReceived);
        }

		/// <summary>
        /// Close the comm port
        /// </summary>
        public void closeConnection()
        {
            if (_BluetoothConnection.IsOpen)
                _BluetoothConnection.Close();
        }

        /// <summary>
        /// open the comm port
        /// </summary>
        public void openConnection()
        {
            if (!_BluetoothConnection.IsOpen)
                _BluetoothConnection.Open();
        }
		
        /// <summary>
        /// pulls data from the buffer, sends it off to get cleaned up
        /// then fires an event with the payload to any listeners
        /// </summary>
        /// <param name="sender">the comm port object</param>
        /// <param name="e">the event</param>
        private void _BluetoothConnection_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort btPort = (SerialPort)sender;

            //The first 2 bytes are the overall packet size
            int packetSize = btPort.ReadByte();
            packetSize += btPort.ReadByte() << 8;

            byte[] buffer = new byte[packetSize];

            btPort.Read(buffer,0,packetSize);
			
			//If we have an event subscriber send them the payload
			if(rxtx != null)
				rxtx(payloadToString(buffer));

            //If we have an event subscriber send them the payload
            if (messageReceived != null)
            {
                //send the message off to be dealt with
                messageReceived(parsedPayload);
            }
            
        }   
        
        /// <summary>
        /// Send data over the comPort
        /// </summary>
        /// <param name="message">The byte array to send over the comm port</param>
        private void writeData(byte[] message)
        {
            openConnection();
            //set the LSB to the length of the message 
            MessageLength[0] = (byte) message.Length;
            MessageLength[1] = (byte)(message.Length >> 8);
            //send the 2 bytes header 
            _BluetoothConnection.Write(MessageLength, 0, MessageLength.Length);
            
            //send the actual payload
            _BluetoothConnection.Write(message, 0, message.Length);
            rxtx("Tx: " + payloadToString(message));
        }

        private string payloadToString(byte[] payload)
        {
            string payloadAsString = "";
            foreach (byte payloadData in payload)
            {
                payloadAsString += payloadData.ToString() + ",";
            }

            return payloadAsString;
        }
    }

